package com.example.demo.config;

import com.alibaba.druid.pool.DruidDataSource;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
public class DruidDBConfig {
  private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
  
  private static final String DB_HOST_ENV_KEY = "MYSQL_SERVICE_HOST";
  
  private static final String DB_PORT_ENV_KEY = "MYSQL_SERVICE_PORT";
  
  @Value("${spring.datasource.url}")
  public String dbUrl;
  
  @Value("${spring.datasource.username}")
  public String username;
  
  @Value("${spring.datasource.password}")
  public String password;
  
  @Value("${spring.datasource.driverClassName}")
  private String driverClassName;
  
  @Value("${spring.datasource.initialSize}")
  private int initialSize;
  
  @Value("${spring.datasource.minIdle}")
  private int minIdle;
  
  @Value("${spring.datasource.maxActive}")
  private int maxActive;
  
  @Value("${spring.datasource.maxWait}")
  private int maxWait;
  
  @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
  private int timeBetweenEvictionRunsMillis;
  
  @Value("${spring.datasource.minEvictableIdleTimeMillis}")
  private int minEvictableIdleTimeMillis;
  
  @Value("${spring.datasource.validationQuery}")
  private String validationQuery;
  
  @Value("${spring.datasource.testWhileIdle}")
  private boolean testWhileIdle;
  
  @Value("${spring.datasource.testOnBorrow}")
  private boolean testOnBorrow;
  
  @Value("${spring.datasource.testOnReturn}")
  private boolean testOnReturn;
  
  @Value("${spring.datasource.poolPreparedStatements}")
  private boolean poolPreparedStatements;
  
  @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
  private int maxPoolPreparedStatementPerConnectionSize;
  
  @Value("${spring.datasource.filters}")
  private String filters;
  
  @Value("${spring.datasource.connectionProperties}")
  private String connectionProperties;
  
  @Value("${spring.datasource.dbName}")
  private String dbName;
  
  @Bean
  @Primary
  public DataSource dataSource() {
    DruidDataSource datasource = new DruidDataSource();
    Map<String, String> envMap = System.getenv();
    if (envMap.containsKey("MYSQL_SERVICE_HOST") && !((String)envMap.get("MYSQL_SERVICE_HOST")).equals("")) {
      if (envMap.containsKey("MYSQL_SERVICE_PORT") && !((String)envMap.get("MYSQL_SERVICE_PORT")).equals("")) {
        String mysql_dbUrl = "jdbc:mysql://" + (String)envMap.get("MYSQL_SERVICE_HOST") + ":" + (String)envMap.get("MYSQL_SERVICE_PORT") + "/" + this.dbName;
        System.out.println("mysql address get from env.");
        System.out.println("mysql address: " + mysql_dbUrl);
        datasource.setUrl(mysql_dbUrl);
      } else {
        String mysql_dbUrl = "jdbc:mysql://" + (String)envMap.get("MYSQL_SERVICE_HOST") + ":3306/" + this.dbName;
        System.out.println("mysql host and port get from env.");
        System.out.println("mysql address: " + mysql_dbUrl);
        datasource.setUrl(mysql_dbUrl);
      } 
    } else {
      System.out.println("mysql address get from local properties config.");
      System.out.println("mysql address: " + this.dbUrl);
      datasource.setUrl(this.dbUrl);
    } 
    datasource.setUsername(this.username);
    datasource.setPassword(this.password);
    datasource.setDriverClassName(this.driverClassName);
    datasource.setInitialSize(this.initialSize);
    datasource.setMinIdle(this.minIdle);
    datasource.setMaxActive(this.maxActive);
    datasource.setMaxWait(this.maxWait);
    datasource.setTimeBetweenEvictionRunsMillis(this.timeBetweenEvictionRunsMillis);
    datasource.setMinEvictableIdleTimeMillis(this.minEvictableIdleTimeMillis);
    datasource.setValidationQuery(this.validationQuery);
    datasource.setTestWhileIdle(this.testWhileIdle);
    datasource.setTestOnBorrow(this.testOnBorrow);
    datasource.setTestOnReturn(this.testOnReturn);
    datasource.setPoolPreparedStatements(this.poolPreparedStatements);
    datasource.setMaxPoolPreparedStatementPerConnectionSize(this.maxPoolPreparedStatementPerConnectionSize);
    try {
      datasource.setFilters(this.filters);
    } catch (SQLException e) {
      this.logger.error("druid configuration initialization filter", e);
    } 
    datasource.setConnectionProperties(this.connectionProperties);
    return (DataSource)datasource;
  }
}
